package edu.gatech.volt2.drdoommgt.tests;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import edu.gatech.volt2.drdoommgt.domain.*;

import static org.junit.Assert.*;


public class Persistance {
	
	private static Logger myLogger = Logger.getLogger("edu.gatech.volt2.drdoommgt.tests.Persistance");

	
	@javax.persistence.PersistenceContext private static EntityManagerFactory emf = null;
	private static EntityManager em = null;
	
	@BeforeClass public static void connectToDatabase(){
		try{
			Persistance.emf = Persistence.createEntityManagerFactory("testing");
			Persistance.em = Persistance.emf.createEntityManager(); 	// Retrieve an application managed entity manager
		}catch(Throwable t){
			// Something didn't work.. these should work... fail
			t.printStackTrace();
			fail();
		}
	}
	
	@AfterClass public static void closeConnectionToDatabase(){
//		Persistance.em.close();
//		Persistance.emf.close();
	}
	
	@Test public void connectonUp(){
//		assertNotNull(Persistance.em);
//		assertTrue(Persistance.em.isOpen());
	}
	
	@Test public void entityManagerTransactions(){
//		Persistance.em.getTransaction().begin();
//		// Did the transaction open?
//		assertTrue(Persistance.em.getTransaction().isActive());
//		Persistance.em.getTransaction().commit();
//		// Did the transaction close
//		assertEquals(false, Persistance.em.getTransaction().isActive());
	}
	
	@Test public void userClassPersistance(){
		User testUser = new User(new Name("Testing", "User"));
		
		Persistance.em.getTransaction().begin();
		
		// Save the user
		Persistance.em.persist( testUser );
		long newUserId = testUser.getId();
		
		// is the new user's id set? ( > 0 )
		assertTrue((newUserId>0));
		
		User testFoundUser = Persistance.em.find(User.class, newUserId);
		// test that we got the user back out of the database
		assertTrue(testUser.equals(testFoundUser));
		
		// Garbage collect testFoundUser
		testFoundUser = null;
		
		// Now we remove it from persistence
		Persistance.em.remove( testUser );
		
		Persistance.em.getTransaction().commit();
		
	}
	
	@After public void flushEmAfterTest(){
		// Flush after each test to insure they do not interfear with eachother
		//Persistance.em.flush();
	}
	
	
	@Test public void testFindByEmail(){
		
		
		User testUser = new User(new Name("Testing", "User"));
		testUser.setEmail("james.k.rundt@gmail.com");
		
		Persistance.em.getTransaction().begin();

		// Save the user
		Persistance.em.persist( testUser );
		Persistance.em.flush();
		Persistance.em.getTransaction().commit();

		Query findByEmailQuery=null;
		boolean found= true;

		findByEmailQuery = Persistance.em.createQuery("from User where email = :email");
		findByEmailQuery.setParameter("email", "james.k.rundquist@gmail.com");

		User foundUser= new User();
		if(found)
		{
			try
			{
				foundUser = (User) findByEmailQuery.getSingleResult();
				assertEquals("james.k.rundquist@gmail.com", foundUser.getEmail());
			}
			catch(NoResultException e)
			{
	            myLogger.log(Level.SEVERE, "Email address was not found.", e);

				System.out.println("Email address was not found.");
			}
		}
		else
		{
			assertEquals("null", foundUser.getEmail());
		}
		
		Persistance.em.getTransaction().begin();
		Persistance.em.remove( testUser );
		Persistance.em.getTransaction().commit();
		
	}
	
	@Test public void testLogin()
	{
		
		User loginUser = new User(new Name("Login", "Test"));
		loginUser.setEmail("perron.jones@gmail.com");
		loginUser.setPassword("Yessir");
		String correctPassword= loginUser.getPassword();
		//System.out.println(correctPassword);
		
		Persistance.em.getTransaction().begin();
		
		// Save the user
		Persistance.em.persist(loginUser);
		
		long newUserId = loginUser.getId();
		
		// is the new user's id set? ( > 0 )
		assertTrue((newUserId>0));
		
		User testFoundUser = Persistance.em.find(User.class, newUserId);
		// test that we got the user back out of the database
		assertTrue(loginUser.equals(testFoundUser));
		assertEquals(correctPassword,testFoundUser.getPassword());

		
		
		Login log= new Login(loginUser);
		//7fb1387bf8533b67fb474ae968246f5ef931d509ae67a15f96a7f9a28718bafc - LoginUser

		Persistance.em.persist(loginUser);

		
		assertEquals(false, loginUser.isLoggedIn());
		
		loginUser = log.loginProcess(loginUser);
		
		assertEquals(true, loginUser.isLoggedIn());

		Persistance.em.persist( loginUser );
		Persistance.em.flush();
		Persistance.em.remove( loginUser );
		Persistance.em.getTransaction().commit();
	}
	
	
	
}
